package service

import (
	"encoding/json"
	"math"
	"os"
	"sync"
	"time"
	"wanfang-translation/internal/service/exception"

	"github.com/spf13/viper"
)

// 统计时间模块，用于统计各个模块的运行时间

// ModuleStats 结构体定义
type ModuleStats struct {
	TotalTime      time.Duration // 运行总时间
	TotalCount     int           // 运行总次数
	TotalCharCount int64         // TODO: 处理的总字符数，运行时间过长或者字符数过多的时候可能会出现超过int64的情况，后续不统计该字段
	AverageTime    time.Duration // 平均运行时间
}

// ModuleStatsJson 结构体定义，用于存储到文件中
type ModuleStatsJson struct {
	TotalTime      float64 `json:"total_time"`       // 运行总时间（秒）
	TotalCount     int     `json:"total_count"`      // 运行总次数
	TotalCharCount int64   `json:"total_char_count"` // 处理的总字符数
	AverageTime    float64 `json:"average_time"`     // 平均运行时间（秒）
}

// Statistics 结构体定义
type Statistics struct {
	mu    sync.Mutex              // 互斥锁
	stats map[string]*ModuleStats // 模块统计信息
}

// 全局变量
var addCountTotal int64

// NewStatistics 创建新的 Statistics 实例
func NewStatistics() *Statistics {
	return &Statistics{
		stats: make(map[string]*ModuleStats),
	}
}

// AddStats 添加统计信息，每百次写入一次文件
func (s *Statistics) AddStats(moduleName string, moduleStats *ModuleStats) {
	s.mu.Lock()
	defer s.mu.Unlock()

	if _, exists := s.stats[moduleName]; !exists {
		s.stats[moduleName] = &ModuleStats{}
	}

	s.stats[moduleName].TotalTime += moduleStats.TotalTime
	s.stats[moduleName].TotalCount += 1
	s.stats[moduleName].TotalCharCount += moduleStats.TotalCharCount

	addCountTotal++
	if addCountTotal%100 == 0 {
		// 从配置文件中读取持久化路径
		statusPath := viper.GetString("file_save.status_path")
		err := s.SaveStatsToFile(statusPath + "/statistics.json")
		if err != nil {
			exception.LogError(exception.NewSystemError("保存统计信息失败" + err.Error()))
			return
		}

		// 如果超过int64的最大值的一半，重置为0
		if addCountTotal >= math.MaxInt64/2 {
			addCountTotal = 0
		}
	}

}

// GetStats 获取统计信息
func (s *Statistics) GetStats(moduleName string) *ModuleStats {
	s.mu.Lock()
	defer s.mu.Unlock()

	if stats, exists := s.stats[moduleName]; exists {
		return stats
	}
	return nil
}

// convertToModuleStatsJson 将 ModuleStats 转换为 ModuleStatsJson
func (s *Statistics) convertToModuleStatsJson() map[string]*ModuleStatsJson {
	statsJson := make(map[string]*ModuleStatsJson)
	for key, stats := range s.stats {
		statsJson[key] = &ModuleStatsJson{
			TotalTime:      stats.TotalTime.Seconds(),
			TotalCount:     stats.TotalCount,
			TotalCharCount: stats.TotalCharCount,
			AverageTime:    stats.AverageTime.Seconds(),
		}
	}
	return statsJson
}

// SaveStatsToFile 将统计信息持久化到文件中
func (s *Statistics) SaveStatsToFile(filename string) error {

	file, err := os.Create(filename)
	if err != nil {
		return err
	}
	defer file.Close()
	// 计算平均时间 = 总时间 / 总次数
	for _, stats := range s.stats {
		stats.AverageTime = stats.TotalTime / time.Duration(stats.TotalCount)
	}

	// 转换类型
	statsJson := s.convertToModuleStatsJson()

	encoder := json.NewEncoder(file)
	if err := encoder.Encode(statsJson); err != nil {
		return err
	}

	return nil
}

// getStatistics 获取统计信息
func (s *Statistics) GetStatistics() map[string]*ModuleStats {
	return s.stats
}
